package com.github.ecbp.common.data.aspect;

import com.alibaba.fastjson.JSONObject;
import com.github.ecbp.common.security.utils.CommonAdminUtils;
import com.github.ecbp.common.utils.IpAddressUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

@Component
@Aspect
public class ResourceLogAspect {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("execution(public * com.github.ecbp.*.service.controller.*..*(..))")
    public void resourceLog() {
    }

    @Around("resourceLog()")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        final long startTime = System.currentTimeMillis();
        HttpServletRequest request = attributes.getRequest();
        String url = request.getRequestURL().toString();
        String ip = IpAddressUtils.getIpAddress(request);
        String methodName = joinPoint.getSignature().getName();
        Long id = CommonAdminUtils.getLoginIdFromSystem();
        String username = CommonAdminUtils.getLoginPhoneFromToken();
        Object[] args = joinPoint.getArgs();
        long threadId = Thread.currentThread().getId();
        try{
            logger.info("线程ID：[{}] >>>>>>>>>>>>>> 用户名称:{},用户id:{},URL:{},用户IP地址:{},方法名称:{},方法参数:{}",
                    threadId, username, id, url, ip, methodName,
                    Optional.ofNullable(args).map(JSONObject::toJSONString).orElse(null));
        }catch(Exception e){
            logger.info("线程ID：[{}] >>>>>>>>>>>>>> 用户名称:{},用户id:{},URL:{},用户IP地址:{},方法名称:{},方法参数:{}",
                    threadId, username, id, url, ip, methodName,
                    Optional.ofNullable(args).orElse(null));
        }
        final Object result = joinPoint.proceed();
        String reslutJson = Optional.ofNullable(result).map(JSONObject::toJSONString).orElse(null);
        logger.info("线程ID：[{}] >>>>>>>>>>>>>> 请求返回值:{},消耗时间(毫秒):{}",
                threadId, reslutJson, (System.currentTimeMillis() - startTime));
        return result;
    }
}
